package com.hmdp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hmdp.dto.Result;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.Follow;
import com.hmdp.mapper.FollowMapper;
import com.hmdp.service.IFollowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.service.IUserService;
import com.hmdp.utils.ThreadLocalUtil;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements IFollowService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private IUserService userService;
    /**
     * 关注或者取消关注
     *
     * @param followUserId
     * @param isFollow
     * @return
     */

    //当前用户的关注set的key的前缀
    private static final String FOLLOWS_KEY_PREFIX = "follows:";

    @Override
    public Result follow(Long followUserId, Boolean isFollow) {
        //1.获取当前登录用户
        Long currentUserId = getCurrentUserId();
        if (currentUserId == null) {
            //如果用户未登录，则返回错误信息
            return Result.fail("请先登录");
        }
        String key = FOLLOWS_KEY_PREFIX + currentUserId;//当前用户的关注set的key
        //2.判断当前用户是否关注了该用户
        if (isFollow) {
            //进行关注
            Follow follow = new Follow();
            follow.setUserId(currentUserId);
            follow.setFollowUserId(followUserId);
            follow.setCreateTime(LocalDateTime.now());
            //保存关注信息
            boolean saveIsSuccess = save(follow);
            if (!saveIsSuccess) {
                return Result.fail("关注失败");
            }
            //把当前用户id放入redis的set集合中，代表该用户关注了该用户
            stringRedisTemplate.opsForSet().add(key, followUserId.toString());
        } else {
            //取消关注
            boolean removeIsSuccess = remove(new QueryWrapper<Follow>().eq("user_id", currentUserId).eq("follow_user_id", followUserId));
            //从redis的set集合中移除当前用户id，代表该用户取消关注了该用户
            if (removeIsSuccess) {
                //从redis的set集合中移除当前用户id
                stringRedisTemplate.opsForSet().remove(key, followUserId.toString());
            }
        }
        //3.返回结果
        return Result.ok();
    }


    /**
     * 查询是否关注
     *
     * @param followUserId
     * @return
     */
/*    @Override
    public Result isFollow(Long followUserId) {
        Long currentUserId = getCurrentUserId();
        //2.1 获取关注对象
        Follow one = query().eq("user_id", currentUserId).eq("follow_user_id", followUserId).one();
        return Result.ok(one!= null);
    }*/
    @Override
    public Result isFollow(Long followUserId) {
        Long currentUserId = getCurrentUserId();
        //2.1 获取关注对象
        Integer count = query().eq("user_id", currentUserId).eq("follow_user_id", followUserId).count();
        return Result.ok(count > 0);
    }

    /**
     * 共同关注
     *
     * @param id
     * @return
     */
    @Override
    public Result followCommons(Long id) {
        //1.获取当前登录用户
        Long currentUserId = getCurrentUserId();
        //2.获取当前用户和目标用户的关注集合key
        String key = FOLLOWS_KEY_PREFIX + currentUserId;
        String targetKey = FOLLOWS_KEY_PREFIX + id;
        //3.求交集
        Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key, targetKey);
        if (intersect == null || intersect.isEmpty()) {
            log.warn("没有共同关注的用户");
            return Result.ok(Collections.emptyList());
        }
        //4.解析交集
        List<Long> collect = intersect.stream().map(Long::valueOf).toList();
        //5.查询用户信息,并转换为List<UserDTO>
        List<UserDTO> userDTOS = userService.listByIds(collect).stream().map(user -> {
            return BeanUtil.copyProperties(user, UserDTO.class);
        }).toList();
        //6.返回结果
        return Result.ok(userDTOS);
    }



    private static Long getCurrentUserId() {
        /*获取用户信息*/
        UserDTO currentUser = (UserDTO) ThreadLocalUtil.get();
        Long currentUserId = currentUser.getId();
        return currentUserId;
    }


}
